package com.zhiyou100.review.day017.homework;


import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Objects;
import java.util.Scanner;

/**
 * @packageName: HomeworkOfFile
 * @className: com.zhiyou100.review.day017.homework
 * @Description: TODO june 28 2020 IO 作业
 * @author: yang
 * @date: 6/28/20
 */
public class HomeworkOfFile {

    /**
     * @Description: TODO 获取 文件或者文件夹的字节大小
     * @name: getLength
     * @param: [path]
     * @return: long
     * @date: 6/28/20 11:26
     * @author: yang
     */
    private static long getLength(String path) {
        // 1 封装对象
        File file = new File(path);
        if (!file.exists()) {
            // 如果不存在
            throw new RuntimeException(path + "该目录不存在!");
        }
        if (file.isFile()) {
            // 如果是文件
            return file.length();
        }
        // 如果是文件夹
        long length = 0;
        for (File file1 : Objects.requireNonNull(file.listFiles())) {
            // 遍历 直接 子文件、子文件夹
            length += getLength(file1.getAbsolutePath());
        }
        return length;

    }

    /**
     * @Description: TODO 写一个方法static void copy(String pathName,String fileName)把fileName对应的文件/文件夹拷贝到pathName目录下
     * @name: copy
     * @param: [old, now]
     * @return: void
     * @date: 6/28/20 19:17
     * @author: yang
     */
    public static void copy(String old, String now) throws Exception {
        //1 就行合理判断：yuan、muDi必须存在
        File oldFile = new File(old);
        if (!oldFile.exists()) {
            throw new RuntimeException("源文件:" + oldFile.getAbsolutePath() + "不存在！");
        }
        File muDiFile = new File(now);
        if (!muDiFile.exists()) {
            if (!muDiFile.mkdirs()) {
                throw new RuntimeException("目的文件:" + oldFile.getAbsolutePath() + "创建失败！");
            }
        }
        //2 判断源文件的类型
        if (oldFile.isFile()) {
            File nowFile = new File(muDiFile, oldFile.getName());
            //需要在muDiFile下创建一个与yuanFile同名的文件
            //把源文件复制到目的目录中
            FileInputStream fin = new FileInputStream(oldFile);
            //创建输入流与源文件关联：：：把目的文件中的信息读到内存中
            FileOutputStream fileOutputStream = new FileOutputStream(nowFile);
            //创建输出流与目的文件关联：：：  输出流可以自动创建目的文件
//		    while(true){//选择读写方法：逐个字节的读写
//		    	int n=fin.read();//定义变量记录读取的字节信息
//		    	if(n==-1){break;}//判断是否到达文件末尾
//		    	fout.write(n);//把读取的信息通过输出流写出去
//		    }
            while (true) {
                //选择读写方式：逐个字节数组的读写
                byte[] arr = new byte[1024];
                //创建一个数组 装读取的字节
                int n = fin.read(arr, 0, 1024);
                //使用arr来记录读取的字节  记录最多1024个  n记录的读取的有效字节数
                if (n == -1) {
                    break;
                }
                fileOutputStream.write(arr, 0, n);
                //把读取的信息通过输出流写出去
            }
            fin.close();
            fileOutputStream.close();//关闭流
            return;
        }
        //说明是文件夹   获取文件夹下的所有子文件  把子文件拷贝到muDiFileNew下
        //需要在muDiFile下创建一个与yuanFile同名的文件夹
        File muDiFileNew = new File(muDiFile, oldFile.getName());
        muDiFileNew.mkdirs();
        File[] fileZis = oldFile.listFiles();
        //遍历yuanFile文件夹下的所有子文件
        assert fileZis != null;
        for (File zi : fileZis) {
            //要把zi拷贝到muDiFileNew文件夹下
            copy(zi.getAbsolutePath(), muDiFileNew.getAbsolutePath());
        }
    }

    /**
     * @Description: TODO  删除参数文件/参数文件夹
     * @name: delete
     * @param: [fileName]
     * @return: void
     * @date: 6/28/20 11:29
     * @author: yang
     */
    private static void delete(String fileName) {
        try {
            File file = new File(fileName);
            if (file.isDirectory()) {
                // 如果目录，判断有没有子目录和子文件
                File[] file1 = file.listFiles();
                // 把此目录下的所有文件提取,判断file1的长度
                String stringNull = "[]";
                if (stringNull.equals(Arrays.toString(file1))) {
                    //如果为空说明没有子文件和子文件夹，删除
                    file.delete();
                } else {
                    // 说明有子文件和子文件夹，递归删除
                    File[] file2 = new File[file1.length + 1];
                    // 创建一个新的长度+1的数组，用来放本身的目录
                    System.arraycopy(file1, 0, file2, 0, file1.length);
                    // 遍历赋值
                    file2[file2.length - 1] = file1[0].getParentFile();
                    // 把自身的目录，放入file2中
                    String temp = Arrays.toString(file2);
                    // 放此目录下的所有文件和目录
                    String temp1 = temp.substring(1, temp.length() - 1) + ", ";
                    // 去掉开头和结尾的' [ '
                    String[] temp2 = temp1.split(", ");
                    // 分割
                    for (String s :
                            temp2) {
                        // 递归删除
                        delete(s);
                    }
                }
            } else if (file.isFile()) {
                // 如果是文件删除
                file.delete();
            } else {
                System.out.println("啥也不是");
            }
        } catch (Exception e) {
            System.out.println("不是目录或文件");
        }
    }

    /**
     * @Description: TODO 字节流练习1：使用字节流把a文件中的数据写到b文件中
     * @name: getOneFileToOtherFile
     * @param: [a, b]
     * @return: void
     * @date: 6/28/20 16:04
     * @author: yang
     */
    private static void getOneFileToOtherFile(String a, String b) throws IOException {
        File fileA = new File(a);
        File fileB = new File(b);
        // 创建 File

        FileInputStream fileInputStream = new FileInputStream(fileA);
        // 创建输入流
        FileOutputStream fileOutputStream = new FileOutputStream(fileB);
        // 创建输入流

        byte[] bytes = new byte[2];
        // 用数组放置 读取的字节
        while (true) {
            int n = fileInputStream.read(bytes, 0, bytes.length);
            // 获取 读取的字节数
            if (n == -1) {
                // 为 -1 说明到末尾了，跳出
                break;
            }
            fileOutputStream.write(bytes);
            // 写入 到 b 文件中
            fileOutputStream.flush();
            // flush 一次
        }
        fileInputStream.close();
        fileOutputStream.close();
        // 关闭流
    }


    /**
     * @Description: TODO 使用字节流把a文件中的数据转换后写到b文件中  大写转换为小写 小写转换为大写 删除数字
     * @name: getOneFileToOtherFileChange
     * @param: [a, b]
     * @return: void
     * @date: 6/28/20 16:29
     * @author: yang
     */
    private static void getOneFileToOtherFileChange(String a, String b) throws IOException {
        File fileA = new File(a);
        File fileB = new File(b);
        // 创建 File

        FileInputStream fileInputStream = new FileInputStream(fileA);
        // 创建输入流
        FileOutputStream fileOutputStream = new FileOutputStream(fileB);
        // 创建输入流

        byte[] bytes = new byte[2];
        // 用数组放置 读取的字节
        while (true) {
            int n = fileInputStream.read(bytes, 0, bytes.length);
            // 获取 读取的字节数
            if (n == -1) {
                // 为 -1 说明到末尾了，跳出
                break;
            }
            for (byte aByte : bytes) {
                char oneChar = (char) aByte;
                // 转为 Character
                if (Character.isUpperCase(oneChar)) {
                    // 大写转小写
                    fileOutputStream.write(Character.toLowerCase(oneChar));
                } else if (Character.isLowerCase(oneChar)) {
                    // 小写转大写
                    fileOutputStream.write(Character.toUpperCase(oneChar));
                } else if (!Character.isDigit(oneChar)) {
                    // 删除数字
                    fileOutputStream.write(oneChar);
                }
            }
            fileOutputStream.flush();
            // flush 一次
        }
        fileInputStream.close();
        fileOutputStream.close();
        // 关闭流
    }


    /**
     * @Description: TODO 把键盘写入的数据 数字写入a文件中  非数字写入b文件中
     * @name: getKayBoardToFile
     * @param: [a, b]
     * @return: void
     * @date: 6/28/20 16:29
     * @author: yang
     */
    private static void getKayBoardToFile(String a, String b) throws IOException {
        Scanner scanner = new Scanner(System.in);
        String s = scanner.nextLine();
        // 获取 键盘输入
        FileOutputStream fileA = new FileOutputStream(a);
        FileOutputStream fileB = new FileOutputStream(b);
        // 创建 输出流
        for (byte c : s.getBytes()) {
            if (Character.isDigit(c)) {
                // 是 数字
                fileA.write(c);
                fileA.flush();
            } else {
                // 不是 数字
                fileB.write(c);
                fileB.flush();
            }
        }
        fileA.close();
        fileB.close();
        // 关闭 流

    }


    /**
     * @Description: TODO 完善后的 copy 方法
     * @name: copyTwo
     * @param: [old, now]
     * @return: void
     * @date: 6/28/20 19:25
     * @author: yang
     */
    public static void copyTwo(String old, String now) throws Exception {
        //1 就行合理判断：yuan、muDi必须存在
        File oldFile = new File(old);
        if (!oldFile.exists()) {
            throw new RuntimeException("源文件:" + oldFile.getAbsolutePath() + "不存在！");
        }
        File muDiFile = new File(now);
        if (!muDiFile.exists()) {
            if (!muDiFile.mkdirs()) {
                throw new RuntimeException("目的文件:" + oldFile.getAbsolutePath() + "创建失败！");
            }
        }
        //2 判断源文件的类型
        if (oldFile.isFile()) {
            File nowFile = new File(muDiFile, oldFile.getName());
            //需要在muDiFile下创建一个与yuanFile同名的文件
            //把源文件复制到目的目录中
            FileInputStream fin = new FileInputStream(oldFile);
            //创建输入流与源文件关联：：：把目的文件中的信息读到内存中
            FileOutputStream fileOutputStream = new FileOutputStream(nowFile);
            //创建输出流与目的文件关联：：：  输出流可以自动创建目的文件
//		    while(true){//选择读写方法：逐个字节的读写
//		    	int n=fin.read();//定义变量记录读取的字节信息
//		    	if(n==-1){break;}//判断是否到达文件末尾
//		    	fout.write(n);//把读取的信息通过输出流写出去
//		    }
            while (true) {
                //选择读写方式：逐个字节数组的读写
                byte[] arr = new byte[1024];
                //创建一个数组 装读取的字节
                int n = fin.read(arr, 0, 1024);
                //使用arr来记录读取的字节  记录最多1024个  n记录的读取的有效字节数
                if (n == -1) {
                    break;
                }
                fileOutputStream.write(arr, 0, n);
                //把读取的信息通过输出流写出去
            }
            fin.close();
            fileOutputStream.close();//关闭流
            return;
        }
        //说明是文件夹   获取文件夹下的所有子文件  把子文件拷贝到muDiFileNew下
        //需要在muDiFile下创建一个与yuanFile同名的文件夹
        File muDiFileNew = new File(muDiFile, oldFile.getName());
        muDiFileNew.mkdirs();
        File[] fileZis = oldFile.listFiles();
        //遍历yuanFile文件夹下的所有子文件
        assert fileZis != null;
        for (File zi : fileZis) {
            //要把zi拷贝到muDiFileNew文件夹下
            copyTwo(zi.getAbsolutePath(), muDiFileNew.getAbsolutePath());
        }
    }

    /**
     * @Description: TODO 写一个方法addOne(Student s,String file)把s的信息写到目的文件file中 每个学生一行：1001-韩梅梅-18-98.5
     * @name: addOne
     * @param: [s, file]
     * @return: void
     * @date: 6/28/20 19:35
     * @author: yang
     */
    private static void addOne(Student s, String file) throws IOException {
        File fileName = new File(file);
        // 创建 file
        if (!fileName.exists()) {
            // 如果文件不存在
            throw new RuntimeException(fileName.getAbsolutePath() + " 不存在！");
        }
        if (fileName.isDirectory()) {
            // 是个文件夹
            throw new RuntimeException(fileName.getAbsolutePath() + " 是个文件夹！");
        }
        String student = s.toString();
        // 获取 字符串信息

        BufferedReader reader = new BufferedReader(new FileReader(fileName));
        // 创建一个 缓冲字符流

        StringBuilder stringBuilder = new StringBuilder();
        // 创建一个 StringBuilder 放置信息

        while (true) {
            String line = reader.readLine();
            // 记录读到的数据，不加换行符
            if (line == null) {
                // 读到 末尾，退出
                break;
            }
            stringBuilder.append(line).append(System.lineSeparator());
            // + 换行符 放到 stringBuilder 中
        }
        reader.close();
        stringBuilder.append(student).append(System.lineSeparator());
        // 加入添加的学生信息

        BufferedWriter writer = new BufferedWriter(new FileWriter(fileName));
        // 创建输入流
        writer.write(String.valueOf(stringBuilder));
        // 写入
        writer.flush();
        // 推送

        writer.close();
        // 关闭


    }


    /**
     * @Description: TODO  写一个方法deleteOne(int sid,String file)  把file中 指定sid的行数据删除
     * @name: delOne
     * @param: [id, filePath]
     * @return: void
     * @date: 6/28/20 21:10
     * @author: yang
     */
    private static void delOne(int id, String filePath) throws IOException {
        File fileName = new File(filePath);
        // 创建 file
        if (!fileName.exists()) {
            // 如果文件不存在
            throw new RuntimeException(fileName.getAbsolutePath() + " 不存在！");
        }
        if (fileName.isDirectory()) {
            // 是个文件夹
            throw new RuntimeException(fileName.getAbsolutePath() + " 是个文件夹！");
        }
        if (!isExistTheId(id, filePath)) {
            throw new RuntimeException("id " + id + " 不存在");
        }

        ArrayList<Student> all = getAll(filePath);
        // 获取所有的学生

        for (Object o : all.toArray()) {
            Student student = (Student) o;
            if (student.getId() == id) {
                // 找到 删除
                all.remove(student);
                break;
            }
        }

        BufferedWriter writer = new BufferedWriter(new FileWriter(fileName));
        // 创建输出流
        for (Student student : all) {
            writer.write(student.toString());
            // student 写入
            writer.newLine();
            // 写入一个换行符
            writer.flush();
            // 刷新
        }
        writer.close();
        // 关闭


    }


    /**
     * @Description: TODO 获取所有的学生集合
     * @name: getAll
     * @param: [file]
     * @return: java.util.ArrayList<com.zhiyou100.review.day017.homework.Student>
     * @date: 6/28/20 20:50
     * @author: yang
     */
    private static ArrayList<Student> getAll(String file) throws IOException {
        File fileName = new File(file);
        // 创建 file
        if (!fileName.exists()) {
            // 如果文件不存在
            throw new RuntimeException(fileName.getAbsolutePath() + " 不存在！");
        }
        if (fileName.isDirectory()) {
            // 是个文件夹
            throw new RuntimeException(fileName.getAbsolutePath() + " 是个文件夹！");
        }

        ArrayList<Student> students = new ArrayList<>();
        BufferedReader reader = new BufferedReader(new FileReader(fileName));
        while (true) {
            String line = reader.readLine();
            // 读取一行，不加换行符
            if (line == null) {
                // 读到末尾，跳出
                break;
            }

            students.add(inStringGetStudent(line));
            // 添加到 students 中
        }
        reader.close();
        // 关闭 读取流

        return students;
    }


    /**
     * @Description: TODO  把file中sid对应的学生的分数更改为score
     * @name: updateOne
     * @param: [file, id, score]
     * @return: void
     * @date: 6/28/20 21:12
     * @author: yang
     */
    private static void updateOne(String filePath, int id, double score) throws IOException {
        File fileName = new File(filePath);
        // 创建 file
        if (!fileName.exists()) {
            // 如果文件不存在
            throw new RuntimeException(fileName.getAbsolutePath() + " 不存在！");
        }
        if (fileName.isDirectory()) {
            // 是个文件夹
            throw new RuntimeException(fileName.getAbsolutePath() + " 是个文件夹！");
        }
        if (!isExistTheId(id, filePath)) {
            throw new RuntimeException("id " + id + " 不存在");
        }

        ArrayList<Student> all = getAll(filePath);
        // 获取所有的学生

        for (int i = 0; i < all.size(); i++) {
            Student student = all.get(i);
            if (student.getId() == id) {
                // 找到，更改
                student.setScore(score);
                // 设置
                all.set(i, student);
                // 更改集合
                break;
            }
        }

        BufferedWriter writer = new BufferedWriter(new FileWriter(fileName));
        // 创建输出流
        for (Student student : all) {
            writer.write(student.toString());
            // student 写入
            writer.newLine();
            // 写入一个换行符
            writer.flush();
            // 刷新
        }
        writer.close();
        // 关闭
    }

    /**
     * @Description: TODO 判断是否存在该 id
     * @name: isExistTheId
     * @param: [id]
     * @return: boolean
     * @date: 6/28/20 20:53
     * @author: yang
     */
    private static boolean isExistTheId(int id, String filePath) throws IOException {
        boolean flag = false;
        for (Student student : getAll(filePath)) {
            if (student.getId() == id) {
                // 找到 id 相同的 flag = true，跳出
                flag = true;
                break;
            } else {
                flag = false;
            }
        }
        return flag;

    }

    /**
     * @Description: TODO 从字符串中读取一个 student 对象
     * @name: inStringGetStudent
     * @param: [line]
     * @return: com.zhiyou100.review.day017.homework.Student
     * @date: 6/28/20 20:45
     * @author: yang
     */
    private static Student inStringGetStudent(String line) {
        String[] split = line.split("-");
        int id = Integer.parseInt(split[0]);
        int age = Integer.parseInt(split[2]);
        String name = split[1];
        double score = Double.parseDouble(split[3]);
        return new Student(id, age, name, score);
    }

    public static void main(String[] args) throws IOException {
        String fileName = "/Users/yang/Downloads/test/student.txt";

    }
}

class Student {
    /**
     * @Description: TODO 随机创建一个学生
     * @name: randomOneStudent
     * @param: []
     * @return: com.zhiyou100.review.day017.homework.Student
     * @date: 6/28/20 20:20
     * @author: yang
     */
    public static Student randomOneStudent() {
        int id = RandomUtil.randomInt(1, 10000);
        int age = RandomUtil.randomInt(15, 30);
        String name = "张" + id;
        double score = NumberUtil.round(RandomUtil.randomDouble(0, 100), 2).doubleValue();
        return new Student(id, age, name, score);
    }

    private int id;
    private int age;
    private String name;
    private double score;

    @Override
    public String toString() {
        return id + "-" + name + "-" + age + "-" + score;
    }

    public Student() {
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }

    public Student(int id, int age, String name, double score) {
        this.id = id;
        this.age = age;
        this.name = name;
        this.score = score;
    }
}